<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:doc="livcos.org/ns/doc"
  xmlns:f="livcos.org/ns/xslt/function"
  xmlns="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="doc f">
  
  <xsl:import href="../base.xsl"/>
  
  <xsl:template match="doc:value | doc:import | doc:include">
    <span id="{@id}">
      <xsl:apply-templates select="@ref" mode="setRefEntity"/>
    </span>
  </xsl:template>

  <xsl:template match="doc:value" mode="createWithRefEntity">
    <xsl:param name="refEntity"/>
    <xsl:choose>
      <xsl:when test="(@path = 'title') and $refEntity/doc:title">
        <xsl:value-of select="$refEntity/doc:title"/>
      </xsl:when>
      <xsl:when test="(@path = 'label') and $refEntity/doc:label">
        <xsl:value-of select="$refEntity/doc:label"/>
      </xsl:when>
      <xsl:when test="(@path = '@name') and $refEntity/@name">
        <xsl:value-of select="$refEntity/@name"/>
      </xsl:when>
      <xsl:when test="(@path = 'document/head/title') and $refEntity/doc:document/doc:head/doc:title">
        <xsl:value-of select="$refEntity/doc:document/doc:head/doc:title"/>
      </xsl:when>
      <xsl:when test="(@path = 'document/head/name') and $refEntity/doc:document/doc:head/doc:name">
        <xsl:value-of select="$refEntity/doc:document/doc:head/doc:name"/>
      </xsl:when>
      <xsl:when test="(@path = 'document/head/context') and $refEntity/doc:document/doc:head/doc:context">
        <xsl:value-of select="$refEntity/doc:document/doc:head/doc:context"/>
      </xsl:when>
      <xsl:when
        test="(@path = 'document/head/description') and $refEntity/doc:document/doc:head/doc:description">
        <xsl:value-of select="$refEntity/doc:document/doc:head/doc:description"/>
      </xsl:when>
      <xsl:when test="(@path = 'document/head/keywords') and $refEntity/doc:document/doc:head/doc:keywords">
        <xsl:value-of select="$refEntity/doc:document/doc:head/doc:keywords"/>
      </xsl:when>
      <xsl:when test="node()">
        <xsl:apply-templates/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="@ref"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="doc:import" mode="createWithRefEntity">
    <xsl:param name="refEntity"/>
    <span id="{f:object-id($refEntity)}">
      <xsl:choose>
        <xsl:when test="@mode = 'detailed'">
          <xsl:apply-templates select="$refEntity" mode="detailed"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="$refEntity"/>
        </xsl:otherwise>
      </xsl:choose>
    </span>
  </xsl:template>

  <xsl:template match="doc:include" mode="createWithRefEntity">
    <xsl:param name="refEntity"/>
    <xsl:copy-of select="$refEntity"/>
  </xsl:template>
  
  <xsl:function name="f:baseUri">
    <xsl:param name="node"/>
    <xsl:choose>
      <xsl:when test="$node/@base = 'view'">
        <xsl:value-of select="$viewObjId"/>
      </xsl:when>
      <xsl:when test="$node/@base = 'job'">
        <xsl:value-of select="base-uri($jobObject)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="base-uri($node)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

  <!-- An external document. -->
  <xsl:template match="@ref" mode="setRefEntity">
  	<xsl:variable name="uri" select="resolve-uri(., f:baseUri(..))"/>
  	<xsl:choose>
  		<xsl:when test="$uri = base-uri(..)">
  			<xsl:apply-templates select=".." mode="createWithRefEntity">
  				<xsl:with-param name="refEntity" select="/"/>
  			</xsl:apply-templates>
  		</xsl:when>
  		<xsl:when test="doc-available($uri)">
  			<xsl:apply-templates select=".." mode="createWithRefEntity">
  				<xsl:with-param name="refEntity" select="doc($uri)"/>
  			</xsl:apply-templates>
  		</xsl:when>
  		<xsl:otherwise>
  			<xsl:attribute name="style">color: red;</xsl:attribute>
  			<xsl:text>-- dead ref: </xsl:text>
  			<xsl:value-of select="$uri"/>
  			<xsl:text> --</xsl:text>
  		</xsl:otherwise>
  	</xsl:choose>
  </xsl:template>
  
  <!-- Saxon strips out URI fragments even for the doc() function. So
       we need to handle entity ID fragments manually. -->
  <xsl:template match="@ref[contains(., '#')]" mode="setRefEntity">
    <xsl:variable name="uri" select="resolve-uri(substring-before(., '#'), f:baseUri(..))"/>
  	<xsl:variable name="id" select="substring-after(., '#')"/>
  	<xsl:choose>
  		<xsl:when test="$uri = base-uri(..)">
  			<xsl:apply-templates select=".." mode="createWithRefEntity">
  				<xsl:with-param name="refEntity" select="//*[@id = $id]"/>
  			</xsl:apply-templates>
  		</xsl:when>
  		<xsl:when test="doc-available($uri)">
  			<xsl:apply-templates select=".." mode="createWithRefEntity">
  				<xsl:with-param name="refEntity" select="doc($uri)//*[@id = $id]"/>
  			</xsl:apply-templates>
  		</xsl:when>
  		<xsl:otherwise>
  			<xsl:attribute name="style">color: red;</xsl:attribute>
  			<xsl:text>-- dead ref: </xsl:text>
  			<xsl:value-of select="$uri"/>
  			<xsl:text> --</xsl:text>
  		</xsl:otherwise>
  	</xsl:choose>
  </xsl:template>
  
  <!-- Entity within this document. -->
  <xsl:template match="@ref[starts-with(., '#')]" mode="setRefEntity" priority="2">
    <xsl:variable name="id" select="substring(., 2)"/>
    <xsl:apply-templates select=".." mode="createWithRefEntity">
      <xsl:with-param name="refEntity" select="//*[@id = $id]"/>
    </xsl:apply-templates>
  </xsl:template>
  
  <xsl:template match="@ref[. = '#']" mode="setRefEntity" priority="3">
    <xsl:attribute name="class">default</xsl:attribute>
    <xsl:text>-- import --</xsl:text>
  </xsl:template>
  
</xsl:stylesheet>